home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / editors / emacs / xemacs / xemacs-1.004 / xemacs-1 / xemacs-19.13 / src / insdel.c < prev    next >
Encoding:
Text File  |  1995-08-04  |  55.6 KB  |  1,840 lines

  1. /* Buffer insertion/deletion and gap motion for XEmacs.
  2.    Copyright (C) 1985, 1986, 1991, 1992, 1993, 1994
  3.    Free Software Foundation, Inc.
  4.    Copyright (C) 1994, 1995 Amdahl Corporation.
  5.  
  6. This file is part of XEmacs.
  7.  
  8. XEmacs is free software; you can redistribute it and/or modify it
  9. under the terms of the GNU General Public License as published by the
  10. Free Software Foundation; either version 2, or (at your option) any
  11. later version.
  12.  
  13. XEmacs is distributed in the hope that it will be useful, but WITHOUT
  14. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16. for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with XEmacs; see the file COPYING.  If not, write to the Free
  20. Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  21.  
  22. /* Synched up with: Mule 2.0, FSF 19.28. */
  23.  
  24. /* This file has been Mule-ized (but needs more work). */
  25.  
  26. /* Overhauled by Ben Wing, December 1994, for Mule implementation. */
  27.  
  28. /*
  29.    There are three possible ways to specify positions in a buffer.  All
  30.    of these are one-based: the beginning of the buffer is position or
  31.    index 1, and 0 is not a valid position.
  32.    
  33.    As a "buffer position" (typedef Bufpos):
  34.  
  35.       This is an index specifying an offset in characters from the beginning
  36.       of the buffer.  Note that buffer positions are logically *between*
  37.       characters, not on a character.  The difference between two buffer
  38.       positions specifies the number of characters between those
  39.       positions.  Buffer positions are the only kind of position
  40.       externally visible to the user.
  41.  
  42.    As a "byte index" (typedef Bytind):
  43.  
  44.       This is an index over the bytes used to represent that characters
  45.       in the buffer.  If there is no Mule support, this is identical to a
  46.       buffer position, because each character is represented using one
  47.       byte.  However, with Mule support, many characters require two or
  48.       more bytes for their representation, and so a byte index may be
  49.       greater than the corresponding buffer position.
  50.  
  51.    As a "memory index" (typedef Memind):
  52.  
  53.       This is the byte index adjusted for the gap.  For positions before
  54.       the gap, this is identical to the byte index.  For positions after
  55.       the gap, this is the byte index plus the gap size.  There are two
  56.       possible memory indices for the gap position; the memory index at
  57.       the beginning of the gap should always be used, except in code that
  58.       deals with manipulating the gap, where both indices may be seen.
  59.       The address of the character "at" (i.e. following) a particular
  60.       position can be obtained from the formula
  61.  
  62.         buffer_start_address + memory_index(position) - 1
  63.  
  64.       except in the case of characters at the gap position.
  65.  
  66.    Other typedefs:
  67.    ===============
  68.  
  69.       Emchar:
  70.       -------
  71.         This typedef represents a single Emacs character, which can be
  72.     ASCII, ISO-8859, or some extended character, as would typically
  73.     be used for Kanji.  Note that the representation of a character
  74.     as an Emchar is *not* the same as the representation of that
  75.     same character in a string; thus, you cannot do the standard
  76.     C trick of passing a pointer to a character to a function that
  77.     expects a string.
  78.  
  79.     An Emchar takes up 19 bits of representation and (for code
  80.     compatibility and such) is compatible with an int.  This
  81.     representation is visible on the Lisp level.  The important
  82.     characteristics    of the Emchar representation are
  83.  
  84.       -- values 0 - 0x7f represent ASCII.
  85.       -- values 0x80 - 0xff represent the right half of ISO-8859-1.
  86.       -- values 0x100 and up represent all other characters.
  87.  
  88.     This means that Emchar values are upwardly compatible with
  89.     the standard 8-bit representation of ASCII/ISO-8859-1.
  90.  
  91.       Bufbyte:
  92.       --------
  93.         The data in a buffer or string is logically made up of Bufbyte
  94.     objects, where a Bufbyte takes up the same amount of space as a
  95.     char. (It is declared differently, though, to catch invalid
  96.     usages.) Strings stored using Bufbytes are said to be in
  97.     "internal format".  The important characteristics of internal
  98.     format are
  99.  
  100.       -- ASCII characters are represented as a single Bufbyte,
  101.          in the range 0 - 0x7f.
  102.       -- All other characters are represented as a Bufbyte in
  103.          the range 0x80 - 0x9f followed by one or more Bufbytes
  104.          in the range 0xa0 to 0xff.
  105.  
  106.     This leads to a number of desirable properties:
  107.  
  108.       -- Given the position of the beginning of a character,
  109.          you can find the beginning of the next or previous
  110.          character in constant time.
  111.       -- When searching for a substring or an ASCII character
  112.          within the string, you need merely use standard
  113.          searching routines.
  114.  
  115.       array of char:
  116.       --------------
  117.         Strings that go in or out of Emacs are in "external format",
  118.     typedeffed as an array of char or a char *.  There is more
  119.     than one external format (JIS, EUC, etc.) but they all
  120.     have the similar properties.  They are modal encodings,
  121.     which is to say that the meaning of particular bytes is
  122.     not fixed but depends on what "mode" the string is currently
  123.     in (e.g. bytes in the range 0 - 0x7f might be
  124.     interpreted as ASCII, or as Hiragana, or as 2-byte Kanji,
  125.     depending on the current mode).  The mode starts out in
  126.     ASCII/ISO-8859-1 and is switched using escape sequences --
  127.     for example, in the JIS encoding, 'ESC $ B' switches to a
  128.     mode where pairs of bytes in the range 0 - 0x7f
  129.     are interpreted as Kanji characters.
  130.  
  131.     External-formatted data is generally desirable for passing
  132.     data between programs because it is upwardly compatible
  133.     with standard ASCII/ISO-8859-1 strings and may require
  134.     less space than internal encodings such as the one
  135.     described above.  In addition, some encodings (e.g. JIS)
  136.     keep all characters (except the ESC used to switch modes)
  137.     in the printing ASCII range 0x20 - 0x7e, which results in
  138.     a much higher probability that the data will avoid being
  139.     garbled in transmission.  Externally-formatted data is
  140.     generally not very convenient to work with, however, and
  141.     for this reason is usually converted to internal format
  142.     before any work is done on the string.
  143.  
  144.     NOTE: filenames need to be in external format so that
  145.     ISO-8859-1 characters come out correctly.
  146.  
  147.       Charcount:
  148.       ----------
  149.         This typedef represents a count of characters, such as
  150.     a character offset into a string or the number of
  151.     characters between two positions in a buffer.  The
  152.     difference between two Bufpos's is a Charcount, and
  153.     character positions in a string are represented using
  154.     a Charcount.
  155.  
  156.       Bytecount:
  157.       ----------
  158.         Similar to a Charcount but represents a count of bytes.
  159.     The difference between two Bytind's is a Bytecount.
  160.  
  161.     
  162.    Usage of the various representations:
  163.    =====================================
  164.  
  165.    Memory indices are used in low-level functions in insdel.c and for
  166.    extent endpoints and marker positions.  The reason for this is that
  167.    this way, the extents and markers don't need to be updated for most
  168.    insertions, which merely shrink the gap and don't move any
  169.    characters around in memory.
  170.  
  171.    (The beginning-of-gap memory index simplifies insertions w.r.t.
  172.    markers, because text usually gets inserted after markers.  For
  173.    extents, it is merely for consistency, because text can get
  174.    inserted either before or after an extent's endpoint depending on
  175.    the open/closedness of the endpoint.)
  176.  
  177.    Byte indices are used in other code that needs to be fast,
  178.    such as the searching, redisplay, and extent-manipulation code.
  179.  
  180.    Buffer positions are used in all other code.  This is because this
  181.    representation is easiest to work with (especially since Lisp
  182.    code always uses buffer positions), necessitates the fewest
  183.    changes to existing code, and is the safest (e.g. if the text gets
  184.    shifted underneath a buffer position, it will still point to a
  185.    character; if text is shifted under a byte index, it might point
  186.    to the middle of a character, which would be bad).
  187.  
  188.    Similarly, Charcounts are used in all code that deals with strings
  189.    except for code that needs to be fast, which used Bytecounts.
  190.  
  191.    Strings are always passed around internally using internal format.
  192.    Conversions between external format are performed at the time
  193.    that the data goes in or out of Emacs.
  194.    
  195.    Working with the various representations:
  196.    =========================================
  197. */
  198.  
  199. #include <config.h>
  200. #include "lisp.h"
  201.  
  202. #include "buffer.h"
  203. #include "device.h"
  204. #include "frame.h"
  205. #include "extents.h"
  206. #include "insdel.h"
  207. #include "lstream.h"
  208. #include "mule.h"
  209. #include "redisplay.h"
  210.  
  211. /* Various macros modelled along the lines of those in buffer.h.
  212.    Purposefully omitted from buffer.h because files other than this
  213.    one should not be using them. */
  214.  
  215. /* Address of beginning of buffer.  This is an lvalue because
  216.    BUFFER_ALLOC needs it to be. */
  217. #define BUF_BEG_ADDR(buf) ((buf)->text.beg)
  218.  
  219. /* Set the address of beginning of buffer. */
  220. #define SET_BUF_BEG_ADDR(buf, addr) do { (buf)->text.beg = (addr); } while (0)
  221.  
  222. /* Gap size.  */
  223. #define BUF_GAP_SIZE(buf) ((buf)->text.gap_size + 0)
  224.  
  225. /* Set gap size.  */
  226. #define SET_BUF_GAP_SIZE(buf, value) \
  227.   do { (buf)->text.gap_size = (value); } while (0)
  228.  
  229. /* Gap location.  */ 
  230. #define BI_BUF_GPT(buf) ((buf)->text.gpt + 0)
  231. #define BUF_GPT_ADDR(buf) (BUF_BEG_ADDR (buf) + BI_BUF_GPT (buf) - 1)
  232.  
  233. /* Set gap location.  */
  234. #define SET_BI_BUF_GPT(buf, value) do { (buf)->text.gpt = (value); } while (0)
  235.  
  236. /* Set end of buffer.  */ 
  237. #define SET_BI_BUF_Z(buf, value) do { (buf)->text.z = (value); } while (0)
  238.  
  239. /* Under Mule, we maintain two sentinels in the buffer: one at the
  240.    beginning of the gap, and one at the end of the buffer.  This
  241.    allows us to move forward, examining bytes looking for the
  242.    end of a character, and not worry about running off the end.
  243.    We do not need corresponding sentinels when moving backwards
  244.    because we do not have to look past the beginning of a character
  245.    to find the beginning of the character.
  246.  
  247.    Every time we change the beginning of the gap, we have to
  248.    call SET_GAP_SENTINEL().
  249.  
  250.    Every time we change the total size (characters plus gap)
  251.    of the buffer, we have to call SET_END_SENTINEL().
  252.  */
  253.    
  254.  
  255. #ifdef MULE
  256. # define GAP_CAN_HOLD_SIZE_P(buf, len) (BUF_GAP_SIZE (buf) >= (len) + 1)
  257. # define SET_GAP_SENTINEL(buf) (*BUF_GPT_ADDR (buf) = 0)
  258. # define BUF_END_SENTINEL_SIZE 1
  259. # define SET_END_SENTINEL(buf) \
  260.   (*(BUF_BEG_ADDR (buf) + BUF_GAP_SIZE (buf) + BI_BUF_Z (buf) - 1) = 0)
  261. #else
  262. # define GAP_CAN_HOLD_SIZE_P(buf, len) (BUF_GAP_SIZE (buf) >= (len))
  263. # define SET_GAP_SENTINEL(buf)
  264. # define BUF_END_SENTINEL_SIZE 0
  265. # define SET_END_SENTINEL(buf)
  266. #endif
  267.  
  268.  
  269.  
  270.  
  271. /************************************************************************/
  272. /*                     verifying buffer positions                       */
  273. /************************************************************************/
  274.  
  275. /* Return a buffer position stored in a Lisp_Object.  Full
  276.    error-checking is done on the position.  Flags can be specified to
  277.    control the behavior of out-of-range values.  The default behavior
  278.    is to require that the position is within the accessible part of
  279.    the buffer (BEGV and ZV), and to signal an error if the position is
  280.    out of range.
  281.  
  282.    GB_ALLOW_PAST_ACCESSIBLE
  283.  
  284.      The allowable range for the position is the entire buffer
  285.      (BEG and Z), rather than the accessible portion.
  286.  
  287.    GB_COERCE_RANGE
  288.  
  289.      If the position is outside the allowable range, return
  290.      the lower or upper bound of the range, whichever is closer
  291.      to the specified position.
  292.  
  293.    GB_NO_ERROR_IF_BAD
  294.  
  295.      If the position is outside the allowable range, return
  296.      0. */
  297.  
  298. Bufpos
  299. get_bufpos (struct buffer *b, Lisp_Object pos, int flags)
  300. {
  301.   Bufpos ind;
  302.   Bufpos min_allowed, max_allowed;
  303.  
  304.   CHECK_INT_COERCE_MARKER (pos, 0);
  305.   ind = XINT (pos);
  306.   min_allowed = (flags & GB_ALLOW_PAST_ACCESSIBLE) ?
  307.     BUF_BEG (b) : BUF_BEGV (b);
  308.   max_allowed = (flags & GB_ALLOW_PAST_ACCESSIBLE) ?
  309.     BUF_Z (b) : BUF_ZV (b);
  310.     
  311.   if (ind < min_allowed || ind > max_allowed)
  312.     {
  313.       if (flags & GB_COERCE_RANGE)
  314.     ind = ind < min_allowed ? min_allowed : max_allowed;
  315.       else if (flags & GB_NO_ERROR_IF_BAD)
  316.     ind = 0;
  317.       else
  318.     {
  319.       Lisp_Object buffer;
  320.       XSETBUFFER (buffer, b);
  321.       args_out_of_range (buffer, pos);
  322.     }
  323.     }
  324.  
  325.   return ind;
  326. }
  327.  
  328. Bytind
  329. get_bytind (struct buffer *b, Lisp_Object pos, int flags)
  330. {
  331.   Bufpos bpos = get_bufpos (b, pos, flags);
  332.   if (bpos == 0) /* could happen with GB_NO_ERROR_IF_BAD */
  333.     return 0;
  334.   return bufpos_to_bytind (b, bpos);
  335. }
  336.  
  337. /* Return a pair of buffer positions representing a range of text,
  338.    taken from a pair of Lisp_Objects.  Full error-checking is
  339.    done on the positions.  Flags can be specified to control the
  340.    behavior of out-of-range values.  The default behavior is to
  341.    allow the range bounds to be specified in either order
  342.    (however, START will always be the lower bound of the range
  343.    and END the upper bound),to require that the positions
  344.    are within the accessible part of the buffer (BEGV and ZV),
  345.    and to signal an error if the positions are out of range.
  346.  
  347.  
  348.    GB_ALLOW_PAST_ACCESSIBLE
  349.    GB_COERCE_RANGE
  350.    GB_NO_ERROR_IF_BAD
  351.  
  352.      These flags have the same meaning as for get_bufpos_1().
  353.  
  354.    GB_ALLOW_NIL
  355.  
  356.      Either or both positions can be nil.  If FROM is nil,
  357.      START will contain the lower bound of the allowed range.
  358.      If TO is nil, END will contain the upper bound of the
  359.      allowed range.
  360.  
  361.    GB_CHECK_ORDER
  362.  
  363.      FROM must contain the lower bound and TO the upper bound
  364.      of the range.  If the positions are reversed, an error is
  365.      signalled.
  366. */
  367.  
  368. void
  369. get_bufrange (struct buffer *b, Lisp_Object from, Lisp_Object to,
  370.           Bufpos *start, Bufpos *end, unsigned int flags)
  371. {
  372.   Bufpos min_allowed, max_allowed;
  373.  
  374.   min_allowed = (flags & GB_ALLOW_PAST_ACCESSIBLE) ?
  375.     BUF_BEG (b) : BUF_BEGV (b);
  376.   max_allowed = (flags & GB_ALLOW_PAST_ACCESSIBLE) ?
  377.     BUF_Z (b) : BUF_ZV (b);
  378.  
  379.   if (NILP (from) && (flags & GB_ALLOW_NIL))
  380.     *start = min_allowed;
  381.   else
  382.     *start = get_bufpos (b, from, flags | GB_NO_ERROR_IF_BAD);
  383.  
  384.   if (NILP (to) && (flags & GB_ALLOW_NIL))
  385.     *end = max_allowed;
  386.   else
  387.     *end = get_bufpos (b, to, flags | GB_NO_ERROR_IF_BAD);
  388.  
  389.   if ((!*start || !*end) && !(flags & GB_NO_ERROR_IF_BAD))
  390.     {
  391.       Lisp_Object buffer;
  392.       XSETBUFFER (buffer, b);
  393.       args_out_of_range_3 (buffer, from, to);
  394.     }
  395.  
  396.   if (*start && *end && *start > *end)
  397.     {
  398.       if (flags & GB_CHECK_ORDER)
  399.     signal_simple_error_2 ("start greater than end", from, to);
  400.       else
  401.     {
  402.       Bufpos temp;
  403.  
  404.       temp = *start;
  405.       *start = *end;
  406.       *end = temp;
  407.     }
  408.     }
  409. }
  410.  
  411. void
  412. get_bufrange_bytind (struct buffer *b, Lisp_Object from, Lisp_Object to,
  413.              Bytind *start, Bytind *end, unsigned int flags)
  414. {
  415.   Bufpos s, e;
  416.  
  417.   get_bufrange (b, from, to, &s, &e, flags);
  418.   *start = bufpos_to_bytind (b, s);
  419.   *end = bufpos_to_bytind (b, e);
  420. }
  421.  
  422. /************************************************************************/
  423. /*                     point and marker adjustment                      */
  424. /************************************************************************/
  425.  
  426. /* just_set_point() is the only place `PT' is an lvalue in all of emacs.
  427.    This function is called from set_buffer_point(), which is the function
  428.    that the SET_PT and BUF_SET_PT macros expand into, and from the
  429.    routines below that insert and delete text. (This is in cases where
  430.    the point marker logically doesn't move but PT (being a byte index)
  431.    needs to get adjusted.) */
  432.  
  433. /* Set point to a specified value.  This is used only when the value
  434.    of point changes due to an insert or delete; it does not represent
  435.    a conceptual change in point as a marker.  In particular, point is
  436.    not crossing any interval boundaries, so there's no need to use the
  437.    usual SET_PT macro.  In fact it would be incorrect to do so, because
  438.    either the old or the new value of point is out of synch with the
  439.    current set of intervals.  */
  440.  
  441. /* This gets called more than enough to make the function call
  442.    overhead a significant factor so we've turned it into a macro. */
  443. #define JUST_SET_POINT(buf, ind) buf->text.pt = ind
  444.  
  445. /* Set a buffer's point. */
  446.  
  447. void
  448. set_buffer_point (struct buffer *buf, Bytind position)
  449. {
  450.   assert (position >= BI_BUF_BEGV (buf) && position <= BI_BUF_ZV (buf));
  451.   if (position == BI_BUF_PT (buf))
  452.     return;
  453.   JUST_SET_POINT (buf, position);
  454.   MARK_POINT_CHANGED;
  455.   assert (MARKERP (buf->point_marker));
  456.   XMARKER (buf->point_marker)->memind =
  457.     bytind_to_memind (buf, position);
  458.  
  459.   /* FSF makes sure that PT is not being set within invisible text.
  460.      However, this is the wrong place for that check.  The check
  461.      should happen only at the next redisplay. */
  462.  
  463.   /* Some old coder said:
  464.  
  465.      "If there were to be hooks which were run when point entered/left an
  466.      extent, this would be the place to put them.
  467.  
  468.      However, it's probably the case that such hooks should be implemented
  469.      using a post-command-hook instead, to avoid running the hooks as a
  470.      result of intermediate motion inside of save-excursions, for example."
  471.  
  472.      I definitely agree with this.  PT gets moved all over the place
  473.      and it would be a Bad Thing for any hooks to get called, both for
  474.      the reason above and because many callers are not prepared for
  475.      a GC within this function. --ben
  476.    */
  477. }
  478.  
  479. /* Do the correct marker-like adjustment on MPOS (see below).  FROM, TO,
  480.    and AMOUNT are as in adjust_markers().  If MPOS doesn't need to be
  481.    adjusted, nothing will happen. */
  482. Memind
  483. do_marker_adjustment (Memind mpos, Memind from,
  484.               Memind to, Bytecount amount)
  485. {
  486.   if (amount > 0)
  487.     {
  488.       if (mpos > to && mpos < to + amount)
  489.     mpos = to + amount;
  490.     }
  491.   else
  492.     {
  493.       if (mpos > from + amount && mpos <= from)
  494.     mpos = from + amount;
  495.     }
  496.   if (mpos > from && mpos <= to)
  497.     mpos += amount;
  498.   return mpos;
  499. }  
  500.  
  501. /* Do the following:
  502.  
  503.    (1) Add `amount' to the position of every marker in the current buffer
  504.    whose current position is between `from' (exclusive) and `to' (inclusive).
  505.  
  506.    (2) Also, any markers past the outside of that interval, in the direction
  507.    of adjustment, are first moved back to the near end of the interval
  508.    and then adjusted by `amount'.
  509.  
  510.    This function is called in two different cases: when a region of
  511.    characters adjacent to the gap is moved, causing the gap to shift
  512.    to the other side of the region (in this case, `from' and `to'
  513.    point to the old position of the region and there should be no
  514.    markers affected by (2) because they would be inside the gap),
  515.    or when a region of characters adjacent to the gap is wiped out,
  516.    causing the gap to increase to include the region (in this case,
  517.    `from' and `to' are the same, both pointing to the boundary
  518.    between the gap and the deleted region, and there are no markers
  519.    affected by (1)).
  520.    
  521.    The reason for the use of exclusive and inclusive is that markers at
  522.    the gap always sit at the beginning, not at the end.
  523. */
  524.  
  525. static void
  526. adjust_markers (struct buffer *buf, Memind from, Memind to,
  527.         Bytecount amount)
  528. {
  529.   struct Lisp_Marker *m;
  530.  
  531.   for (m = buf->markers; m; m = marker_next (m))
  532.     m->memind = do_marker_adjustment (m->memind, from, to, amount);
  533. }
  534.  
  535.  
  536. /************************************************************************/
  537. /*                  Routines for dealing with the gap                   */
  538. /************************************************************************/
  539.  
  540. /* XEmacs requires an ANSI C compiler, and it damn well better have a
  541.    working memmove() */
  542. #define GAP_USE_BCOPY
  543. #ifdef BCOPY_UPWARD_SAFE
  544. # undef BCOPY_UPWARD_SAFE
  545. #endif
  546. #ifdef BCOPY_DOWNWARD_SAFE
  547. # undef BCOPY_DOWNWARD_SAFE
  548. #endif
  549. #define BCOPY_UPWARD_SAFE 1
  550. #define BCOPY_DOWNWARD_SAFE 1
  551.  
  552. /* maximum amount of memory moved in a single chunk.  Increasing this
  553.    value improves gap-motion efficiency but decreases QUIT responsiveness
  554.    time.  Was 32000 but today's processors are faster and files are
  555.    bigger.  --ben */
  556. #define GAP_MOVE_CHUNK 300000
  557.  
  558. /* Move the gap to POS, which is less than the current GPT. */
  559.  
  560. static void
  561. gap_left (struct buffer *buf, Bytind pos)
  562. {
  563.   Bufbyte *to, *from;
  564.   Bytecount i;
  565.   Bytind new_s1;
  566.  
  567.   from = BUF_GPT_ADDR (buf);
  568.   to = from + BUF_GAP_SIZE (buf);
  569.   new_s1 = BI_BUF_GPT (buf);
  570.  
  571.   /* Now copy the characters.  To move the gap down,
  572.      copy characters up.  */
  573.  
  574.   while (1)
  575.     {
  576.       /* I gets number of characters left to copy.  */
  577.       i = new_s1 - pos;
  578.       if (i == 0)
  579.     break;
  580.       /* If a quit is requested, stop copying now.
  581.      Change POS to be where we have actually moved the gap to.  */
  582.       if (QUITP)
  583.     {
  584.       pos = new_s1;
  585.       break;
  586.     }
  587.       /* Move at most GAP_MOVE_CHUNK chars before checking again for a quit. */
  588.       if (i > GAP_MOVE_CHUNK)
  589.     i = GAP_MOVE_CHUNK;
  590. #ifdef GAP_USE_BCOPY
  591.       if (i >= 128
  592.       /* bcopy is safe if the two areas of memory do not overlap
  593.          or on systems where bcopy is always safe for moving upward.  */
  594.       && (BCOPY_UPWARD_SAFE
  595.           || to - from >= 128))
  596.     {
  597.       /* If overlap is not safe, avoid it by not moving too many
  598.          characters at once.  */
  599.       if (!BCOPY_UPWARD_SAFE && i > to - from)
  600.         i = to - from;
  601.       new_s1 -= i;
  602.       from -= i, to -= i;
  603.       memmove (to, from, i);
  604.     }
  605.       else
  606. #endif
  607.     {
  608.       new_s1 -= i;
  609.       while (--i >= 0)
  610.         *--to = *--from;
  611.     }
  612.     }
  613.  
  614.   /* Adjust markers, and buffer data structure, to put the gap at POS.
  615.      POS is where the loop above stopped, which may be what was specified
  616.      or may be where a quit was detected.  */
  617.   adjust_markers (buf, pos, BI_BUF_GPT (buf), BUF_GAP_SIZE (buf));
  618.   adjust_extents (buf, pos, BI_BUF_GPT (buf), BUF_GAP_SIZE (buf));
  619.   SET_BI_BUF_GPT (buf, pos);
  620.   SET_GAP_SENTINEL (buf);
  621. #ifdef ERROR_CHECK_EXTENTS
  622.   sledgehammer_extent_check (make_buffer (buf));
  623. #endif
  624.   QUIT;
  625. }
  626.  
  627. static void
  628. gap_right (struct buffer *buf, Bytind pos)
  629. {
  630.   Bufbyte *to, *from;
  631.   Bytecount i;
  632.   Bytind new_s1;
  633.  
  634.   to = BUF_GPT_ADDR (buf);
  635.   from = to + BUF_GAP_SIZE (buf);
  636.   new_s1 = BI_BUF_GPT (buf);
  637.  
  638.   /* Now copy the characters.  To move the gap up,
  639.      copy characters down.  */
  640.  
  641.   while (1)
  642.     {
  643.       /* I gets number of characters left to copy.  */
  644.       i = pos - new_s1;
  645.       if (i == 0)
  646.     break;
  647.       /* If a quit is requested, stop copying now.
  648.      Change POS to be where we have actually moved the gap to.  */
  649.       if (QUITP)
  650.     {
  651.       pos = new_s1;
  652.       break;
  653.     }
  654.       /* Move at most GAP_MOVE_CHUNK chars before checking again for a quit. */
  655.       if (i > GAP_MOVE_CHUNK)
  656.     i = GAP_MOVE_CHUNK;
  657. #ifdef GAP_USE_BCOPY
  658.       if (i >= 128
  659.       /* bcopy is safe if the two areas of memory do not overlap
  660.          or on systems where bcopy is always safe for moving downward. */
  661.       && (BCOPY_DOWNWARD_SAFE
  662.           || from - to >= 128))
  663.     {
  664.       /* If overlap is not safe, avoid it by not moving too many
  665.          characters at once.  */
  666.       if (!BCOPY_DOWNWARD_SAFE && i > from - to)
  667.         i = from - to;
  668.       new_s1 += i;
  669.       memmove (to, from, i);
  670.       from += i, to += i;
  671.     }
  672.       else
  673. #endif
  674.     {
  675.       new_s1 += i;
  676.       while (--i >= 0)
  677.         *to++ = *from++;
  678.     }
  679.     }
  680.  
  681.   {
  682.     int gsize = BUF_GAP_SIZE (buf);
  683.     adjust_markers (buf, BI_BUF_GPT (buf) + gsize, pos + gsize, - gsize);
  684.     adjust_extents (buf, BI_BUF_GPT (buf) + gsize, pos + gsize, - gsize);
  685.     SET_BI_BUF_GPT (buf, pos);
  686.     SET_GAP_SENTINEL (buf);
  687. #ifdef ERROR_CHECK_EXTENTS
  688.     sledgehammer_extent_check (make_buffer (buf));
  689. #endif
  690.   }
  691.   QUIT;
  692. }
  693.  
  694. /* Move gap to position `pos'.
  695.    Note that this can quit!  */
  696.  
  697. static void
  698. move_gap (struct buffer *buf, Bytind pos)
  699. {
  700.   if (! BUF_BEG_ADDR (buf))
  701.     abort ();
  702.   if (pos < BI_BUF_GPT (buf))
  703.     gap_left (buf, pos);
  704.   else if (pos > BI_BUF_GPT (buf))
  705.     gap_right (buf, pos);
  706. }
  707.  
  708. /* Make the gap INCREMENT bytes longer.  */
  709.  
  710. static void
  711. make_gap (struct buffer *buf, Bytecount increment)
  712. {
  713.   Bufbyte *result;
  714.   Lisp_Object tem;
  715.   Bytind real_gap_loc;
  716.   Bytecount old_gap_size;
  717.  
  718.   /* If we have to get more space, get enough to last a while.  We use
  719.      a geometric progession that saves on realloc space. */
  720.   increment += 2000 + ((BI_BUF_Z (buf) - BI_BUF_BEG (buf)) / 8);
  721.  
  722.   result = BUFFER_REALLOC (buf->text.beg,
  723.                BI_BUF_Z (buf) - BI_BUF_BEG (buf) +
  724.                BUF_GAP_SIZE (buf) + increment +
  725.                BUF_END_SENTINEL_SIZE);
  726.   if (result == 0)
  727.     memory_full ();
  728.   SET_BUF_BEG_ADDR (buf, result);
  729.  
  730.   /* Prevent quitting in move_gap.  */
  731.   tem = Vinhibit_quit;
  732.   Vinhibit_quit = Qt;
  733.  
  734.   real_gap_loc = BI_BUF_GPT (buf);
  735.   old_gap_size = BUF_GAP_SIZE (buf);
  736.  
  737.   /* Call the newly allocated space a gap at the end of the whole space.  */
  738.   SET_BI_BUF_GPT (buf, BI_BUF_Z (buf) + BUF_GAP_SIZE (buf));
  739.   SET_BUF_GAP_SIZE (buf, increment);
  740.  
  741.   /* Move the new gap down to be consecutive with the end of the old one.
  742.      This adjusts the markers properly too.  */
  743.   gap_left (buf, real_gap_loc + old_gap_size);
  744.  
  745.   /* Now combine the two into one large gap.  */
  746.   SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + old_gap_size);
  747.   SET_BI_BUF_GPT (buf, real_gap_loc);
  748.   SET_GAP_SENTINEL (buf);
  749.  
  750.   /* We changed the total size of the buffer (including gap),
  751.      so we need to fix up the end sentinel. */
  752.   SET_END_SENTINEL (buf);
  753.  
  754.   Vinhibit_quit = tem;
  755. }
  756.  
  757.  
  758. /************************************************************************/
  759. /*                     Before/after-change processing                   */
  760. /************************************************************************/
  761.  
  762. /* Those magic changes ... */
  763.  
  764. static void
  765. buffer_signal_changed_region (struct buffer *buf, Bufpos start,
  766.                   Bufpos end)
  767. {
  768.   if (buf->changes->begin_unchanged < 0 ||
  769.       buf->changes->begin_unchanged > start - BUF_BEG (buf))
  770.     buf->changes->begin_unchanged = start - BUF_BEG (buf);
  771.   if (buf->changes->end_unchanged < 0 ||
  772.       buf->changes->end_unchanged > BUF_Z (buf) - end)
  773.     buf->changes->end_unchanged = BUF_Z (buf) - end;
  774. }
  775.  
  776. void
  777. buffer_extent_signal_changed_region (struct buffer *buf, Bufpos start,
  778.                      Bufpos end)
  779. {
  780.   if (buf->changes->begin_extent_unchanged < 0 ||
  781.       buf->changes->begin_extent_unchanged > start - BUF_BEG (buf))
  782.     buf->changes->begin_extent_unchanged = start - BUF_BEG (buf);
  783.   if (buf->changes->end_extent_unchanged < 0 ||
  784.       buf->changes->end_extent_unchanged > BUF_Z (buf) - end)
  785.     buf->changes->end_extent_unchanged = BUF_Z (buf) - end;
  786. }
  787.  
  788. void
  789. buffer_reset_changes (struct buffer *buf)
  790. {
  791.   buf->changes->begin_unchanged = -1;
  792.   buf->changes->end_unchanged = -1;
  793.   buf->changes->begin_extent_unchanged = -1;
  794.   buf->changes->end_extent_unchanged = -1;
  795.   buf->changes->newline_was_deleted = 0;
  796. }
  797.  
  798. static void
  799. signal_after_change (struct buffer *buf, Bufpos start, Bufpos orig_end,
  800.              Bufpos new_end);
  801.  
  802. /* Call the after-change-functions according to the changes made so far
  803.    and treat all further changes as single until the outermost
  804.    multiple change exits.  This is called when the outermost multiple
  805.    change exits and when someone is trying to make a change that violates
  806.    the constraints specified in begin_multiple_change(), typically
  807.    when nested multiple-change sessions occur. (There are smarter ways of
  808.    dealing with nested multiple changes, but these rarely occur so there's
  809.    probably no point in it.) */
  810.  
  811. /* #### This needs to keep track of what actually changed and only
  812.    call the after-change functions on that region. */
  813.  
  814. static void
  815. cancel_multiple_change (struct buffer *buf)
  816. {
  817.   /* This function can GC */
  818.   /* Call the after-change-functions except when they've already been
  819.      called or when there were no changes made to the buffer at all. */
  820.   if (buf->changes->mc_begin != 0 && buf->changes->mc_begin_signaled)
  821.     {
  822.       Bufpos real_mc_begin = buf->changes->mc_begin;
  823.       buf->changes->mc_begin = 0;
  824.  
  825.       signal_after_change (buf, real_mc_begin, buf->changes->mc_orig_end,
  826.                buf->changes->mc_new_end);
  827.     }
  828. }
  829.  
  830. /* this is an unwind_protect, to ensure that the after-change-functions
  831.    get called even in a non-local exit. */
  832.  
  833. static Lisp_Object
  834. multiple_change_finish_up (Lisp_Object buffer)
  835. {
  836.   struct buffer *buf = XBUFFER (buffer);
  837.   /* This function can GC */
  838.   buf->changes->in_multiple_change = 0; /* do this first so that errors in
  839.                        the after-change functions don't
  840.                        mess things up. */
  841.   cancel_multiple_change (buf);
  842.   return Qnil;
  843. }
  844.  
  845. /* Call this function when you're about to make a number of buffer changes
  846.    that should be considered a single change. (e.g. `replace-match' calls
  847.    this.) You need to specify the START and END of the region that is
  848.    going to be changed so that the before-change-functions are called
  849.    with the correct arguments.  The after-change region is calculated
  850.    automatically, however, and if changes somehow or other happen outside
  851.    of the specified region, that will also be handled correctly.
  852.  
  853.    begin_multiple_change() returns a number (actually a specpdl depth)
  854.    that you must pass to end_multiple_change() when you are done. */
  855.    
  856. int
  857. begin_multiple_change (struct buffer *buf, Bufpos start, Bufpos end)
  858. {
  859.   /* This function can GC */
  860.   int count = -1;
  861.   if (buf->changes->in_multiple_change)
  862.     {
  863.       if (buf->changes->mc_begin != 0 &&
  864.       (start < buf->changes->mc_begin || end > buf->changes->mc_new_end))
  865.     cancel_multiple_change (buf);
  866.     }
  867.   else
  868.     {
  869.       Lisp_Object buffer;
  870.  
  871.       buf->changes->mc_begin = start;
  872.       buf->changes->mc_orig_end = buf->changes->mc_new_end = end;
  873.       buf->changes->mc_begin_signaled = 0;
  874.       count = specpdl_depth ();
  875.       XSETBUFFER (buffer, buf);
  876.       record_unwind_protect (multiple_change_finish_up, buffer);
  877.     }
  878.   buf->changes->in_multiple_change++;
  879.   /* We don't call before-change-functions until signal_before_change()
  880.      is called, in case there is a read-only or other error. */
  881.   return count;
  882. }
  883.  
  884. void
  885. end_multiple_change (struct buffer *buf, int count)
  886. {
  887.   assert (buf->changes->in_multiple_change > 0);
  888.   buf->changes->in_multiple_change--;
  889.   if (!buf->changes->in_multiple_change)
  890.     unbind_to (count, Qnil);
  891. }
  892.  
  893. static int inside_change_hook;
  894.  
  895. static Lisp_Object
  896. change_function_restore (Lisp_Object buffer)
  897. {
  898.   Fset_buffer (buffer);
  899.   inside_change_hook = 0;
  900.   return Qnil;
  901. }
  902.  
  903. static int in_first_change;
  904.  
  905. static Lisp_Object
  906. first_change_hook_restore (Lisp_Object buffer)
  907. {
  908.   Fset_buffer (buffer);
  909.   in_first_change = 0;
  910.   return Qnil;
  911. }
  912.  
  913. /* Signal an initial modification to the buffer.  */
  914.  
  915. static void
  916. signal_first_change (struct buffer *buf)
  917. {
  918.   /* This function can GC */
  919.   Lisp_Object buffer;
  920.   XSETBUFFER (buffer, buf);
  921.  
  922.   if (!in_first_change)
  923.     {
  924.       if (!NILP (symbol_value_in_buffer (Qfirst_change_hook, buffer)) &&
  925.       !NILP (Vrun_hooks))
  926.     {
  927.       int speccount = specpdl_depth ();
  928.       record_unwind_protect (first_change_hook_restore, buffer);
  929.       set_buffer_internal (buf);
  930.       in_first_change = 1;
  931.       call1 (Vrun_hooks, Qfirst_change_hook);
  932.       unbind_to (speccount, Qnil);
  933.     }
  934.     }
  935. }
  936.  
  937. /* Signal a change to the buffer immediately before it happens.
  938.    START and END are the bounds of the text to be changed. */
  939.  
  940. static void
  941. signal_before_change (struct buffer *buf, Bufpos start, Bufpos end)
  942. {
  943.   /* This function can GC */
  944.   Lisp_Object buffer;
  945.   XSETBUFFER (buffer, buf);
  946.  
  947.   if (!inside_change_hook)
  948.     {
  949.       /* Are we in a multiple-change session? */
  950.       if (buf->changes->in_multiple_change && buf->changes->mc_begin != 0)
  951.     {
  952.       /* If we're violating the constraints of the session,
  953.          call the after-change-functions as necessary for the
  954.          changes already made and treat further changes as
  955.          single. */
  956.       if (start < buf->changes->mc_begin ||
  957.           end > buf->changes->mc_new_end)
  958.         cancel_multiple_change (buf);
  959.       /* Do nothing if this is not the first change in the session. */
  960.       else if (buf->changes->mc_begin_signaled)
  961.         return;
  962.       else
  963.         {
  964.           /* First time through; call the before-change-functions
  965.          specifying the entire region to be changed. (Note that
  966.          we didn't call before-change-functions in
  967.          begin_multiple_change() because the buffer might be
  968.          read-only, etc.) */
  969.           start = buf->changes->mc_begin;
  970.           end = buf->changes->mc_new_end;
  971.         }
  972.     }
  973.  
  974.       /* If buffer is unmodified, run a special hook for that case.  */
  975.       if (buf->save_modified >= BUF_MODIFF (buf))
  976.     signal_first_change (buf);
  977.  
  978.       /* Now in any case run the before-change-functions if any.  */
  979.  
  980.       if ((!NILP (symbol_value_in_buffer (Qbefore_change_functions, buffer)) ||
  981.        /* Obsolete, for compatibility */
  982.        !NILP (symbol_value_in_buffer (Qbefore_change_function, buffer))) &&
  983.       !NILP (Vrun_hooks))
  984.     {
  985.       int speccount = specpdl_depth ();
  986.       record_unwind_protect (change_function_restore, Fcurrent_buffer ());
  987.       set_buffer_internal (buf);
  988.       inside_change_hook = 1;
  989.       run_hook_with_args (Qbefore_change_functions, 2,
  990.                   make_number (start), make_number (end));
  991.       /* Obsolete, for compatibility */
  992.       run_hook_with_args (Qbefore_change_function, 2,
  993.                   make_number (start), make_number (end));
  994.        unbind_to (speccount, Qnil);
  995.     }
  996.  
  997.       /* Only now do we indicate that the before-change-functions have
  998.      been called, in case some function throws out. */
  999.       buf->changes->mc_begin_signaled = 1;
  1000.     }
  1001. }
  1002.  
  1003. /* Signal a change immediately after it happens.
  1004.    START is the bufpos of the start of the changed text.
  1005.    ORIG_END is the bufpos of the end of the before-changed text.
  1006.    NEW_END is the bufpos of the end of the after-changed text.
  1007.  */
  1008.  
  1009. static void
  1010. signal_after_change (struct buffer *buf, Bufpos start, Bufpos orig_end,
  1011.              Bufpos new_end)
  1012. {
  1013.   /* This function can GC */
  1014.   Lisp_Object buffer;
  1015.   XSETBUFFER (buffer, buf);
  1016.  
  1017.   /* always do this. */
  1018.   buffer_signal_changed_region (buf, start, new_end);
  1019.   font_lock_maybe_update_syntactic_caches (buf, start, orig_end, new_end);
  1020.  
  1021.   if (!inside_change_hook)
  1022.     {
  1023.       if (buf->changes->in_multiple_change && buf->changes->mc_begin != 0)
  1024.     {
  1025.       assert (start >= buf->changes->mc_begin &&
  1026.           start <= buf->changes->mc_new_end);
  1027.       assert (orig_end >= buf->changes->mc_begin &&
  1028.           orig_end <= buf->changes->mc_new_end);
  1029.       buf->changes->mc_new_end += new_end - orig_end;
  1030.       return; /* after-change-functions signalled when all changes done */
  1031.     }
  1032.  
  1033.       if ((!NILP (symbol_value_in_buffer (Qafter_change_functions, buffer)) ||
  1034.        /* Obsolete, for compatibility */
  1035.        !NILP (symbol_value_in_buffer (Qafter_change_function, buffer))) &&
  1036.       !NILP (Vrun_hooks))
  1037.     {
  1038.       int speccount = specpdl_depth ();
  1039.       record_unwind_protect (change_function_restore, Fcurrent_buffer ());
  1040.       set_buffer_internal (buf);
  1041.       inside_change_hook = 1;
  1042.       /* The actual after-change functions take slightly
  1043.          different arguments than what we were passed. */
  1044.       run_hook_with_args (Qafter_change_functions, 3,
  1045.                   make_number (start), make_number (new_end),
  1046.                   make_number (orig_end - start));
  1047.       /* Obsolete, for compatibility */
  1048.       run_hook_with_args (Qafter_change_function, 3,
  1049.                   make_number (start), make_number (new_end),
  1050.                   make_number (orig_end - start));
  1051.        unbind_to (speccount, Qnil);
  1052.     }
  1053.     }
  1054. }
  1055.  
  1056. /* Call this if you're about to change the region of BUFFER from START
  1057.    to END.  This checks the read-only properties of the region, calls
  1058.    the necessary modification hooks, and warns the next redisplay that
  1059.    it should pay attention to that area.  */
  1060.  
  1061. static void
  1062. prepare_to_modify_buffer (struct buffer *buf, Bufpos start, Bufpos end,
  1063.               int lockit)
  1064. {
  1065.   /* This function can GC */
  1066.   barf_if_buffer_read_only (buf, start, end);
  1067.  
  1068.   /* #### At this point we should map over extents calling
  1069.      modification-hooks, insert-before-hooks and insert-after-hooks
  1070.      of relevant extents */
  1071.  
  1072.   /* if this is the first modification, see about locking the buffer's
  1073.      file */
  1074.   if (!NILP (buf->filename) && lockit &&
  1075.       buf->save_modified >= BUF_MODIFF (buf))
  1076.     {
  1077. #ifdef CLASH_DETECTION
  1078.       lock_file (buf->filename);
  1079. #else
  1080.       Lisp_Object buffer;
  1081.       XSETBUFFER (buffer, buf);
  1082.       /* At least warn if this file has changed on disk since it was visited.*/
  1083.       if (NILP (Fverify_visited_file_modtime (buffer))
  1084.       && !NILP (Ffile_exists_p (buf->filename)))
  1085.     call1_in_buffer (buf, intern ("ask-user-about-supersession-threat"),
  1086.              buf->filename);
  1087. #endif /* not CLASH_DETECTION */
  1088.     }
  1089.  
  1090.   signal_before_change (buf, start, end);
  1091.  
  1092.   /* BUF_MODIFF (buf)++; -- should be done by callers (insert, delete range)
  1093.      else record_first_change isn't called */
  1094. }
  1095.  
  1096.  
  1097. /************************************************************************/
  1098. /*                        Insertion of strings                          */
  1099. /************************************************************************/
  1100.  
  1101. void
  1102. fixup_internal_substring (CONST Bufbyte *nonreloc, Lisp_Object reloc,
  1103.               int offset, int *len)
  1104. {
  1105.   assert ((nonreloc && NILP (reloc)) || (!nonreloc && STRINGP (reloc)));
  1106.  
  1107.   if (*len < 0)
  1108.     {
  1109.       if (nonreloc)
  1110.     *len = strlen ((char *) nonreloc) - offset;
  1111.       else
  1112.     *len = string_length (XSTRING (reloc)) - offset;
  1113.     }
  1114.   assert (*len >= 0);
  1115.   if (STRINGP (reloc))
  1116.     {
  1117.       assert (offset >= 0 && offset <= string_length (XSTRING (reloc)));
  1118.       assert (offset + *len <= string_length (XSTRING (reloc)));
  1119.     }
  1120. }
  1121.  
  1122. /* Insert a string into BUF at Bufpos POS.  The string data comes
  1123.    from one of two sources: constant, non-relocatable data (specified
  1124.    in NONRELOC), or a Lisp string object (specified in RELOC), which
  1125.    is relocatable and may have extent data that needs to be copied
  1126.    into the buffer.  OFFSET and LENGTH specify the substring of the
  1127.    data that is actually to be inserted.  As a special case, if POS
  1128.    is -1, insert the string at point and move point to the end of the
  1129.    string.
  1130.  
  1131.    Normally, markers at the insertion point end up before the
  1132.    inserted string.  If INSDEL_BEFORE_MARKERS is set in flags, however,
  1133.    they end up after the string.
  1134.  
  1135.    INSDEL_NO_LOCKING is kludgy and is used when insert-file-contents is
  1136.    visiting a new file; it inhibits the locking checks normally done
  1137.    before modifying a buffer.  Similar checks were already done
  1138.    in the higher-level Lisp functions calling insert-file-contents. */
  1139.  
  1140. void
  1141. buffer_insert_string_1 (struct buffer *buf, Bufpos pos,
  1142.             CONST Bufbyte *nonreloc, Lisp_Object reloc,
  1143.             Bytecount offset, Bytecount length,
  1144.             int flags)
  1145. {
  1146.   /* This function can GC */
  1147.   struct gcpro gcpro1, gcpro2;
  1148.   Lisp_Object dup_list = Qnil;
  1149.   Bytind ind;
  1150.   Charcount cclen;
  1151.   int move_point = 0;
  1152.  
  1153.   fixup_internal_substring (nonreloc, reloc, offset, &length);
  1154.  
  1155.   if (pos == -1)
  1156.     {
  1157.       pos = BUF_PT (buf);
  1158.       move_point = 1;
  1159.     }
  1160.  
  1161. #ifdef I18N3
  1162.   /* #### See the comment in print_internal().  If this buffer is marked
  1163.      as translatable, then Fgettext() should be called on obj if it
  1164.      is a string. */
  1165. #endif
  1166.  
  1167.   if (STRINGP (reloc))
  1168.     dup_list = string_dups (XSTRING (reloc));
  1169.  
  1170.   /* Make sure that point-max won't exceed the size of an emacs int. */
  1171.   {
  1172.     Lisp_Object temp;
  1173.   
  1174.     XSETINT (temp, (int) (length + BUF_Z (buf)));
  1175.     if ((int) (length + BUF_Z (buf)) != XINT (temp))
  1176.       error ("maximum buffer size exceeded");
  1177.   }
  1178.  
  1179.   /* theoretically not necessary -- caller should GCPRO */
  1180.   GCPRO2 (reloc, dup_list);
  1181.  
  1182.   prepare_to_modify_buffer (buf, pos, pos, !(flags & INSDEL_NO_LOCKING));
  1183.  
  1184.   /* Defensive steps in case the before-change-functions fuck around */
  1185.   if (!BUFFER_LIVE_P (buf))
  1186.     /* Bad bad pre-change function. */
  1187.     return;
  1188.  
  1189.   /* Make args be valid again.  prepare_to_modify_buffer() might have
  1190.      modified the buffer. */
  1191.   if (pos < BUF_BEGV (buf))
  1192.     pos = BUF_BEGV (buf);
  1193.   if (pos > BUF_ZV (buf))
  1194.     pos = BUF_ZV (buf);
  1195.  
  1196.   /* string may have been relocated up to this point */
  1197.   if (STRINGP (reloc))
  1198.     nonreloc = string_data (XSTRING (reloc));
  1199.  
  1200.   ind = bufpos_to_bytind (buf, pos);
  1201.   cclen = bytecount_to_charcount (nonreloc + offset, length);
  1202.  
  1203.   if (ind != BI_BUF_GPT (buf))
  1204.     /* #### if debug-on-quit is invoked and the user changes the
  1205.        buffer, bad things can happen.  This is a rampant problem
  1206.        in Emacs. */
  1207.     move_gap (buf, ind); /* may QUIT */
  1208.   if (! GAP_CAN_HOLD_SIZE_P (buf, length))
  1209.     make_gap (buf, length - BUF_GAP_SIZE (buf));
  1210.  
  1211.   record_insert (buf, pos, cclen);
  1212.   BUF_MODIFF (buf)++;
  1213.   MARK_BUFFERS_CHANGED;
  1214.  
  1215.   /* string may have been relocated up to this point */
  1216.   if (STRINGP (reloc))
  1217.     nonreloc = string_data (XSTRING (reloc));
  1218.  
  1219.   memcpy (BUF_GPT_ADDR (buf), nonreloc + offset, length);
  1220.  
  1221.   SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) - length);
  1222.   SET_BI_BUF_GPT (buf, BI_BUF_GPT (buf) + length);
  1223.   SET_BI_BUF_ZV (buf, BI_BUF_ZV (buf) + length);
  1224.   SET_BI_BUF_Z (buf, BI_BUF_Z (buf) + length);
  1225.   SET_GAP_SENTINEL (buf);
  1226.  
  1227.   process_extents_for_insertion (buf, ind, length);
  1228.  
  1229.   /* Point logically doesn't move, but may need to be adjusted because
  1230.      it's a byte index.  point-marker doesn't change because it's a
  1231.      memory index. */
  1232.   if (BI_BUF_PT (buf) > ind)
  1233.     JUST_SET_POINT (buf, BI_BUF_PT (buf) + length);
  1234.  
  1235.   /* Well, point might move. */
  1236.   if (move_point)
  1237.     BI_BUF_SET_PT (buf, ind + length);
  1238.  
  1239.   if (!NILP (dup_list))
  1240.     splice_in_extent_replicas (buf, pos, cclen,
  1241.                    bytecount_to_charcount (nonreloc, offset),
  1242.                    dup_list);
  1243.  
  1244.   if (flags & INSDEL_BEFORE_MARKERS)
  1245.     {
  1246.       /* ind - 1 is correct because the FROM argument is exclusive.
  1247.      I formerly used DEC_BYTIND() but that caused problems at the
  1248.      beginning of the buffer. */
  1249.       adjust_markers (buf, ind - 1, ind, length);
  1250.     }
  1251.  
  1252.   signal_after_change (buf, pos, pos, pos + cclen);
  1253.  
  1254.   UNGCPRO;
  1255. }
  1256.  
  1257.  
  1258. /* The following functions are interfaces onto the above function,
  1259.    for inserting particular sorts of data.  In all the functions,
  1260.    BUF and POS specify the buffer and location where the insertion is
  1261.    to take place. (If POS is -1, text is inserted at point and point
  1262.    moves forward past the text.) FLAGS is as above. */
  1263.  
  1264. void
  1265. buffer_insert_raw_string_1 (struct buffer *buf, Bufpos pos,
  1266.                 CONST Bufbyte *nonreloc, Bytecount length,
  1267.                 int flags)
  1268. {
  1269.   /* This function can GC */
  1270.   buffer_insert_string_1 (buf, pos, nonreloc, Qnil, 0, length,
  1271.               flags);
  1272. }
  1273.  
  1274. void
  1275. buffer_insert_lisp_string_1 (struct buffer *buf, Bufpos pos, Lisp_Object str,
  1276.                  int flags)
  1277. {
  1278.   /* This function can GC */
  1279.   assert (STRINGP (str));
  1280.   buffer_insert_string_1 (buf, pos, 0, str, 0, string_length (XSTRING (str)),
  1281.               flags);
  1282. }
  1283.  
  1284. /* Insert the null-terminated string S (in external format). */
  1285.  
  1286. void
  1287. buffer_insert_c_string_1 (struct buffer *buf, Bufpos pos, CONST char *s,
  1288.               int flags)
  1289. {
  1290.   /* This function can GC */
  1291.   /* #### This is not correct for I18N4 */
  1292.      
  1293.   CONST char *translated = GETTEXT (s);
  1294.   buffer_insert_string_1 (buf, pos, (Bufbyte *) translated, Qnil, 0,
  1295.               strlen (translated), flags);
  1296. }
  1297.  
  1298. void
  1299. buffer_insert_emacs_char_1 (struct buffer *buf, Bufpos pos, Emchar ch,
  1300.                 int flags)
  1301. {
  1302.   /* This function can GC */
  1303.   Bufbyte str[MAX_EMCHAR_LEN];
  1304.   Bytecount len;
  1305.  
  1306.   len = emchar_to_charptr (ch, str);
  1307.   buffer_insert_string_1 (buf, pos, str, Qnil, 0, len, flags);
  1308. }
  1309.  
  1310. void
  1311. buffer_insert_c_char_1 (struct buffer *buf, Bufpos pos, char c,
  1312.             int flags)
  1313. {
  1314.   /* This function can GC */
  1315.   buffer_insert_emacs_char_1 (buf, pos, (Emchar) (unsigned char) c,
  1316.                   flags);
  1317. }
  1318.   
  1319. void
  1320. buffer_insert_from_buffer_1 (struct buffer *buf, Bufpos pos,
  1321.                  struct buffer *buf2, Bufpos pos2,
  1322.                  Charcount length, int flags)
  1323. {
  1324.   /* This function can GC */
  1325.   Lisp_Object str = make_string_from_buffer (buf2, pos2, length);
  1326.   buffer_insert_string_1 (buf, pos, 0, str, 0, string_length (XSTRING (str)),
  1327.               flags);
  1328. }
  1329.  
  1330.  
  1331. /************************************************************************/
  1332. /*                        Deletion of ranges                            */
  1333. /************************************************************************/
  1334.  
  1335. /* Delete characters in buffer from FROM up to (but not including) TO.  */
  1336.  
  1337. void
  1338. buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags)
  1339. {
  1340.   /* This function can GC */
  1341.   Charcount numdel;
  1342.   Bytind bi_from, bi_to;
  1343.   Bytecount bc_numdel;
  1344.   int shortage;
  1345.  
  1346.   /* Make args be valid */
  1347.   if (from < BUF_BEGV (buf))
  1348.     from = BUF_BEGV (buf);
  1349.   if (to > BUF_ZV (buf))
  1350.     to = BUF_ZV (buf);
  1351.   if ((numdel = to - from) <= 0)
  1352.     return;
  1353.  
  1354.   prepare_to_modify_buffer (buf, from, to, !(flags & INSDEL_NO_LOCKING));
  1355.  
  1356.   /* Defensive steps in case the before-change-functions fuck around */
  1357.   if (!BUFFER_LIVE_P (buf))
  1358.     /* Bad bad pre-change function. */
  1359.     return;
  1360.  
  1361.   /* Make args be valid again.  prepare_to_modify_buffer() might have
  1362.      modified the buffer. */
  1363.   if (from < BUF_BEGV (buf))
  1364.     from = BUF_BEGV (buf);
  1365.   if (to > BUF_ZV (buf))
  1366.     to = BUF_ZV (buf);
  1367.   if ((numdel = to - from) <= 0)
  1368.     return;
  1369.  
  1370.   /* Redisplay needs to know if a newline was in the deleted region.
  1371.      If we've already marked the changed region as having a deleted
  1372.      newline there is no use in performing the check. */
  1373.   if (!buf->changes->newline_was_deleted)
  1374.     {
  1375.       scan_buffer (buf, '\n', from, to, 1, &shortage, 1);
  1376.       if (!shortage)
  1377.     buf->changes->newline_was_deleted = 1;
  1378.     }
  1379.  
  1380.   bi_from = bufpos_to_bytind (buf, from);
  1381.   bi_to = bufpos_to_bytind (buf, to);
  1382.   bc_numdel = bi_to - bi_from;
  1383.  
  1384.   /* Make sure the gap is somewhere in or next to what we are deleting.  */
  1385.   if (bi_to < BI_BUF_GPT (buf))
  1386.     gap_left (buf, bi_to);
  1387.   if (bi_from > BI_BUF_GPT (buf))
  1388.     gap_right (buf, bi_from);
  1389.  
  1390.   record_delete (buf, from, numdel);
  1391.   BUF_MODIFF (buf)++;
  1392.   MARK_BUFFERS_CHANGED;
  1393.  
  1394.   /* Relocate point as if it were a marker.  */
  1395.   if (bi_from < BI_BUF_PT (buf))
  1396.     {
  1397.       if (BI_BUF_PT (buf) < bi_to)
  1398.     JUST_SET_POINT (buf, bi_from);
  1399.       else
  1400.     JUST_SET_POINT (buf, BI_BUF_PT (buf) - bc_numdel);
  1401.     }
  1402.  
  1403.   /* Detach any extents that are completely within the range [FROM, TO],
  1404.      if the extents are detachable.
  1405.  
  1406.      This must come AFTER record_delete(), so that the appropriate extents
  1407.      will be present to be recorded, and BEFORE the gap size is increased,
  1408.      as otherwise we will be confused about where the extents end. */
  1409.   process_extents_for_deletion (buf, bi_from, bi_to, 0);
  1410.  
  1411.   /* Relocate all markers pointing into the new, larger gap
  1412.      to point at the end of the text before the gap.  */
  1413.   adjust_markers (buf,
  1414.           (bi_to + BUF_GAP_SIZE (buf)),
  1415.           (bi_to + BUF_GAP_SIZE (buf)),
  1416.                   (- bc_numdel - BUF_GAP_SIZE (buf)));
  1417.  
  1418.   /* Relocate any extent endpoints just like markers. */
  1419.   adjust_extents_for_deletion (buf, bi_from, bi_to, BUF_GAP_SIZE (buf),
  1420.                    bc_numdel);
  1421.  
  1422.   SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + bc_numdel);
  1423.   SET_BI_BUF_ZV (buf, BI_BUF_ZV (buf) - bc_numdel);
  1424.   SET_BI_BUF_Z (buf, BI_BUF_Z (buf) - bc_numdel);
  1425.   SET_BI_BUF_GPT (buf, bi_from);
  1426.   SET_GAP_SENTINEL (buf);
  1427.  
  1428. #ifdef ERROR_CHECK_EXTENTS
  1429.   sledgehammer_extent_check (make_buffer (buf));
  1430. #endif
  1431.  
  1432.   signal_after_change (buf, from, to, from);
  1433. }
  1434.  
  1435.  
  1436. /************************************************************************/
  1437. /*                    Replacement of characters                         */
  1438. /************************************************************************/
  1439.  
  1440. /* Replace the character at POS in buffer B with CH. */
  1441.  
  1442. void
  1443. buffer_replace_char (struct buffer *b, Bufpos pos, Emchar ch,
  1444.              int not_real_change, int force_lock_check)
  1445. {
  1446.   /* This function can GC */
  1447.   Bufbyte curstr[MAX_EMCHAR_LEN];
  1448.   Bufbyte newstr[MAX_EMCHAR_LEN];
  1449.   Bytecount curlen, newlen;
  1450.  
  1451.   curlen = BUF_FETCH_CHAR_AS_STR (b, pos, curstr);
  1452.   newlen = emchar_to_charptr (ch, newstr);
  1453.  
  1454.   if (curlen == newlen)
  1455.     {
  1456.       /* then we can just replace the text. */
  1457.       prepare_to_modify_buffer (b, pos, pos + 1,
  1458.                 !not_real_change || force_lock_check);
  1459.       /* Defensive steps in case the before-change-functions fuck around */
  1460.       if (!BUFFER_LIVE_P (b))
  1461.     /* Bad bad pre-change function. */
  1462.     return;
  1463.  
  1464.       /* Make args be valid again.  prepare_to_modify_buffer() might have
  1465.      modified the buffer. */
  1466.       if (pos < BUF_BEGV (b))
  1467.     pos = BUF_BEGV (b);
  1468.       if (pos >= BUF_ZV (b))
  1469.     pos = BUF_ZV (b) - 1;
  1470.       if (pos < BUF_BEGV (b))
  1471.     /* no more characters in buffer! */
  1472.     return;
  1473.  
  1474.       if (BUF_FETCH_CHAR (b, pos) == '\n')
  1475.     b->changes->newline_was_deleted = 1;
  1476.       MARK_BUFFERS_CHANGED;
  1477.       if (!not_real_change)
  1478.     {
  1479.       record_change (b, pos, 1);
  1480.       BUF_MODIFF (b)++;
  1481.     }
  1482.       memcpy (BUF_BYTE_ADDRESS (b, pos), newstr, newlen);
  1483.       signal_after_change (b, pos, pos + 1, pos + 1);
  1484.     }
  1485.   else
  1486.     {
  1487.       /* must implement as deletion followed by insertion. */
  1488.       buffer_delete_range (b, pos, pos + 1, 0);
  1489.       /* Defensive steps in case the before-change-functions fuck around */
  1490.       if (!BUFFER_LIVE_P (b))
  1491.     /* Bad bad pre-change function. */
  1492.     return;
  1493.  
  1494.       /* Make args be valid again.  prepare_to_modify_buffer() might have
  1495.      modified the buffer. */
  1496.       if (pos < BUF_BEGV (b))
  1497.     pos = BUF_BEGV (b);
  1498.       if (pos >= BUF_ZV (b))
  1499.     pos = BUF_ZV (b) - 1;
  1500.       if (pos < BUF_BEGV (b))
  1501.     /* no more characters in buffer! */
  1502.     return;
  1503.       buffer_insert_string_1 (b, pos, newstr, Qnil, 0, newlen, 0);
  1504.     }
  1505. }
  1506.  
  1507.  
  1508. /************************************************************************/
  1509. /*                            Basic functions                           */
  1510. /************************************************************************/
  1511.  
  1512. /* #### Semi-incoherent comment:
  1513.  
  1514.    We don't want to use plain old make_string here, because it calls
  1515.    make_uninit_string, which can cause the buffer arena to be
  1516.    compacted.  make_string has no way of knowing that the data has
  1517.    been moved, and thus copies the wrong data into the string.  This
  1518.    doesn't affect most of the other users of make_string, so it should
  1519.    be left as is.  But we should use this function when conjuring
  1520.    buffer substrings.  */
  1521.  
  1522. Lisp_Object
  1523. make_string_from_buffer (struct buffer *buf, Bufpos pos, Charcount length)
  1524. {
  1525.   /* This function can GC */
  1526.   Lisp_Object val;
  1527.   struct gcpro gcpro1;
  1528.   Bytind bi_ind;
  1529.   Bytecount bi_len;
  1530.  
  1531.   bi_ind = bufpos_to_bytind (buf, pos);
  1532.   bi_len = buf_charcount_to_bytecount (buf, bi_ind, length);
  1533.  
  1534.   val = make_uninit_string (bi_len);
  1535.   GCPRO1 (val);
  1536.   set_string_dups (XSTRING (val), replicate_extents (buf, pos, length));
  1537.  
  1538.   {
  1539.     Bytecount len1 = BI_BUF_GPT (buf) - bi_ind;
  1540.     Bufbyte *start1 = BI_BUF_BYTE_ADDRESS (buf, bi_ind);
  1541.     Bufbyte *dest = string_data (XSTRING (val));
  1542.  
  1543.     if (len1 < 0)
  1544.       {
  1545.     /* Completely after gap */
  1546.     memcpy (dest, start1, bi_len);
  1547.       }
  1548.     else if (bi_len <= len1)
  1549.       {
  1550.     /* Completely before gap */
  1551.     memcpy (dest, start1, bi_len);
  1552.       }
  1553.     else
  1554.       {
  1555.     /* Spans gap */
  1556.     Bytind pos2 = bi_ind + len1;
  1557.     Bufbyte *start2 = BI_BUF_BYTE_ADDRESS (buf, pos2);
  1558.  
  1559.     memcpy (dest, start1, len1);
  1560.     memcpy (dest + len1, start2, bi_len - len1);
  1561.       }
  1562.   }
  1563.  
  1564.   UNGCPRO;
  1565.   return val;
  1566. }
  1567.  
  1568. Bufbyte *
  1569. charptr_from_external_static (CONST char *ptr, int len, Bytecount *len_out,
  1570.                   int bin)
  1571. {
  1572. #ifdef MULE
  1573.   ---- no Mule support yet ----;
  1574. #else
  1575.   if (len == -1)
  1576.     len = strlen (ptr);
  1577.   if (len_out)
  1578.     *len_out = (Bytecount) len;
  1579.   return (Bufbyte *) ptr;
  1580. #endif
  1581. }
  1582.  
  1583. char *
  1584. charptr_to_external_static (CONST Bufbyte *ptr, Bytecount len, int *len_out,
  1585.                 int bin)
  1586. {
  1587. #ifdef MULE
  1588.   ---- no Mule support yet ----;
  1589. #else
  1590.   if (len == -1)
  1591.     len = charptr_length (ptr);
  1592.   if (len_out)
  1593.     *len_out = (int) len;
  1594.   return (char *) ptr;
  1595. #endif
  1596. }
  1597.  
  1598. #ifdef MULE
  1599. # define do_string_ext_data_copy(s, dest, len)    ---- no Mule support yet ----
  1600. #else
  1601. # define do_string_ext_data_copy(s, dest, len) \
  1602.   memcpy (dest, string_data (s), len)
  1603. #endif
  1604.  
  1605. static char *string_ext_data_spot[5];
  1606. static int string_ext_data_spot_size[5];
  1607.  
  1608. char *
  1609. string_ext_data_static (struct Lisp_String *s, int bin)
  1610. {
  1611.   int len = string_ext_length (s) + 1; /* must include terminating 0 */
  1612.  
  1613.   assert (bin >= 0 && bin < 5);
  1614.   DO_REALLOC (string_ext_data_spot[bin], string_ext_data_spot_size[bin],
  1615.           len, char);
  1616.   do_string_ext_data_copy (s, string_ext_data_spot[bin], len);
  1617.   return string_ext_data_spot[bin];
  1618. }
  1619.  
  1620. char *
  1621. string_ext_data_malloc (struct Lisp_String *s)
  1622. {
  1623.   int len = string_ext_length (s) + 1; /* must include terminating 0 */
  1624.   char *ptr = (char *) xmalloc (len);
  1625.  
  1626.   do_string_ext_data_copy (s, ptr, len);
  1627.   return ptr;
  1628. }
  1629.  
  1630. void
  1631. barf_if_buffer_read_only (struct buffer *buf, Bufpos from, Bufpos to)
  1632. {
  1633.  back:
  1634.   if (!NILP (Vinhibit_read_only))
  1635.     return;
  1636.   if (!NILP (buf->read_only))
  1637.   {
  1638.     Lisp_Object b;
  1639.     XSETBUFFER (b, buf);
  1640.     Fsignal (Qbuffer_read_only, (list1 (b)));
  1641.     goto back;
  1642.   }
  1643.   if (from > 0)
  1644.   {
  1645.     if (to < 0) to = from;
  1646.     verify_extent_modification (buf,
  1647.                 bufpos_to_bytind (buf, from),
  1648.                 bufpos_to_bytind (buf, to));
  1649.   }
  1650. }
  1651.  
  1652. #ifdef MULE
  1653.  
  1654. /* We include the basic functions here that require no specific
  1655.    knowledge of how data is Mule-encoded into a buffer other
  1656.    than the basic (00 - 7F), (80 - 9F), (A0 - FF) scheme.
  1657.    Anything that requires more specific knowledge goes into
  1658.    mule-charset.c. */
  1659.  
  1660. /* Given a pointer to a text string and a length in bytes, return
  1661.    the equivalent length in characters. */
  1662.  
  1663. Charcount
  1664. bytecount_to_charcount (unsigned char *ptr, Bytecount len)
  1665. {
  1666.   Charcount count = 0;
  1667.   unsigned char *end = ptr + len;
  1668.  
  1669.   while (ptr < end)
  1670.     {
  1671.       count++;
  1672.       INC_CHARPTR_1 (ptr);
  1673.     }
  1674. #ifdef ERROR_CHECK_BUFPOS
  1675.   /* Bomb out if the specified substring ends in the middle
  1676.      of a character.  Note that we might have already gotten
  1677.      a core dump above from an invalid reference, but at least
  1678.      we will get no farther than here. */
  1679.   assert (ptr == end);
  1680. #endif
  1681.   return count;
  1682. }
  1683.  
  1684. /* Given a pointer to a text string and a length in characters, return
  1685.    the equivalent length in bytes. */
  1686.  
  1687. Bytecount
  1688. charcount_to_bytecount (unsigned char *ptr, Charcount len)
  1689. {
  1690.   unsigned char *newptr = ptr;
  1691.  
  1692.   while (len > 0)
  1693.     {
  1694.       INC_CHARPTR_1 (newptr);
  1695.       len--;
  1696.     }
  1697.   return newptr - ptr;
  1698. }
  1699.  
  1700. Bytind
  1701. bufpos_to_bytind (struct buffer *buf, Bufpos x)
  1702. {
  1703.   Bytind retval = (Bytind) x;
  1704.   ASSERT_VALID_BYTIND (buf, retval);
  1705.   ---- no Mule support yet ----;
  1706.   return retval;
  1707. }
  1708.  
  1709. Bufpos
  1710. bytind_to_bufpos (struct buffer *buf, Bytind x)
  1711. {
  1712.   ASSERT_VALID_BYTIND (buf, x);
  1713.   ---- no Mule support yet ----;
  1714.   return (Bufpos) x;
  1715. }
  1716.  
  1717. Charcount
  1718. buf_bytecount_to_charcount (struct buffer *buf, Bytind x, Bytecount len)
  1719. {
  1720.   Charcount count = 0;
  1721.   Bytind end = x + len;
  1722.  
  1723.   ASSERT_VALID_BYTIND (buf, x);
  1724.   ASSERT_VALID_BYTIND (buf, x + len);
  1725.   assert (len >= 0);
  1726.   while (x < end)
  1727.     {
  1728.       INC_BYTIND_1 (buf, x);
  1729.       count++;
  1730.     }
  1731. #ifdef ERROR_CHECK_BUFPOS
  1732.   /* Bomb out if the specified substring ends in the middle
  1733.      of a character.  Note that we might have already gotten
  1734.      a core dump above from an invalid reference, but at least
  1735.      we will get no farther than here. */
  1736.   assert (x == end);
  1737. #endif
  1738.   return count;
  1739. }
  1740.  
  1741. Bytecount
  1742. buf_charcount_to_bytecount (struct buffer *buf, Bytind x, Charcount len)
  1743. {
  1744.   Bytind newx = x;
  1745.  
  1746.   ASSERT_VALID_BYTIND (buf, x);
  1747.   assert (len >= 0);
  1748.   while (len)
  1749.     {
  1750.       INC_BYTIND_1 (buf, newx);
  1751.       len--;
  1752.     }
  1753.   ASSERT_VALID_BYTIND (buf, newx);
  1754.   return newx - x;
  1755. }
  1756.  
  1757. #elif defined (ERROR_CHECK_BUFPOS)
  1758.  
  1759. Bytind
  1760. bufpos_to_bytind (struct buffer *buf, Bufpos x)
  1761. {
  1762.   Bytind retval = (Bytind) x;
  1763.   ASSERT_VALID_BYTIND (buf, retval);
  1764.   return retval;
  1765. }
  1766.  
  1767. Bufpos
  1768. bytind_to_bufpos (struct buffer *buf, Bytind x)
  1769. {
  1770.   ASSERT_VALID_BYTIND (buf, x);
  1771.   return (Bufpos) x;
  1772. }
  1773.  
  1774. Charcount
  1775. buf_bytecount_to_charcount (struct buffer *buf, Bytind x, Bytecount len)
  1776. {
  1777.   ASSERT_VALID_BYTIND (buf, x);
  1778.   ASSERT_VALID_BYTIND (buf, x + len);
  1779.   assert (len >= 0);
  1780.   return (Charcount) len;
  1781. }
  1782.  
  1783. Bytecount
  1784. buf_charcount_to_bytecount (struct buffer *buf, Bytind x, Charcount len)
  1785. {
  1786.   Bytecount retval = (Bytecount) len;
  1787.   ASSERT_VALID_BYTIND (buf, x);
  1788.   ASSERT_VALID_BYTIND (buf, x + retval);
  1789.   assert (len >= 0);
  1790.   return retval;
  1791. }
  1792.  
  1793. #endif /* not MULE and not ERROR_CHECK_BUFPOS */
  1794.  
  1795.  
  1796. /************************************************************************/
  1797. /*                            initialization                            */
  1798. /************************************************************************/
  1799.  
  1800. void
  1801. vars_of_insdel (void)
  1802. {
  1803.   inside_change_hook = 0;
  1804.   in_first_change = 0;
  1805. }
  1806.  
  1807. void
  1808. init_buffer_text (struct buffer *b)
  1809. {
  1810.   SET_BUF_GAP_SIZE (b, 20);
  1811.   (void) BUFFER_ALLOC (b->text.beg, BUF_GAP_SIZE (b) + BUF_END_SENTINEL_SIZE);
  1812.   if (! BUF_BEG_ADDR (b))
  1813.     memory_full ();
  1814.  
  1815.   JUST_SET_POINT (b, 1);
  1816.   SET_BI_BUF_GPT (b, 1);
  1817.   SET_BI_BUF_BEGV (b, 1);
  1818.   SET_BI_BUF_ZV (b, 1);
  1819.   SET_BI_BUF_Z (b, 1);
  1820.   SET_GAP_SENTINEL (b);
  1821.   SET_END_SENTINEL (b);
  1822.   b->changes = (struct buffer_change_data *) xmalloc (sizeof (*b->changes));
  1823.   memset (b->changes, 0, sizeof (*b->changes));
  1824. #ifdef MULE
  1825.   b->mule_data = (struct buffer_mule_bufpos_data *)
  1826.     xmalloc (sizeof (*b->mule_data));
  1827.   memset (b->mule_data, 0, sizeof (*b->mule_data));
  1828. #endif
  1829. }
  1830.  
  1831. void
  1832. uninit_buffer_text (struct buffer *b)
  1833. {
  1834.   BUFFER_FREE (b->text.beg);
  1835.   xfree (b->changes);
  1836. #ifdef MULE
  1837.   xfree (b->mule_data);
  1838. #endif
  1839. }
  1840.